package com.leyou.item.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.leyou.common.enums.ExceptionEnum;
import com.leyou.common.exception.LyException;
import com.leyou.common.utils.BeanHelper;
import com.leyou.common.vo.PageResult;
import com.leyou.item.dto.*;
import com.leyou.item.entity.Sku;
import com.leyou.item.entity.Spu;
import com.leyou.item.entity.SpuDetail;
import com.leyou.item.mapper.SkuMapper;
import com.leyou.item.mapper.SpuDetailMapper;
import com.leyou.item.mapper.SpuMapper;
import com.leyou.item.service.GoodsService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class GoodsServiceImpl implements GoodsService {
    @Autowired
    private SpuMapper spuMapper;
    @Autowired
    private CategoryServiceImpl categoryService;
    @Autowired
    private BrandServiceImpl brandService;
    @Autowired
    private SpuDetailMapper spuDetailMapper;
    @Autowired
    private SkuMapper skuMapper;

    @Override
    public PageResult<SpuDTO> findPage(Integer page, Integer rows, String key, Boolean saleable) {
        PageHelper.startPage(page, rows);
        Example example = new Example(Spu.class);
        Example.Criteria criteria = example.createCriteria();
         if (StringUtils.isNotBlank(key)){
             criteria.andLike("name", "%" + key + "%");
         }
         if (saleable!=null){
             criteria.andEqualTo("saleable", saleable);
         }

        List<Spu> spuList = this.spuMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(spuList)) {
            throw new LyException(ExceptionEnum.DATA_NOT_FOUND);
        }
        PageInfo<Spu> pageInfo = new PageInfo<>(spuList);
        List<SpuDTO> spuDTOS = BeanHelper.copyWithCollection(spuList, SpuDTO.class);
        spuDTOS.forEach(spuDTO -> {
            List<CategoryDTO> list = this.categoryService.queryCategoriesById(spuDTO.getCategoryIds());
            if (CollectionUtils.isEmpty(list)) {
                throw new LyException(ExceptionEnum.DATA_NOT_FOUND);
            }
            String names = list
                    .stream()
                    .map(CategoryDTO::getName)
                    .collect(Collectors.joining("/"));
            spuDTO.setCategoryName(names);
            BrandDTO brandDTO = brandService.queryBrandById(spuDTO.getBrandId());
            spuDTO.setBrandName(brandDTO.getName());
        });
        return new PageResult<>(pageInfo.getTotal(), pageInfo.getPages(), spuDTOS);
    }


    @Override
    @Transactional
    public void saveGoods(SpuDTO spuDTO) {
        System.out.println(spuDTO);
        Spu spu = BeanHelper.copyProperties(spuDTO, Spu.class);
        int count = this.spuMapper.insertSelective(spu);
        if (1 != count) {
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }
        SpuDetailDTO spuDetailDTO = spuDTO.getSpuDetail();
        SpuDetail spuDetail = BeanHelper.copyProperties(spuDetailDTO, SpuDetail.class);
        spuDetail.setSpuId(spu.getId());
        int insert = this.spuDetailMapper.insertSelective(spuDetail);
        if (1 != insert) {
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }
        List<SkuDTO> skus = spuDTO.getSkus();
        List<Sku> skuList = BeanHelper.copyWithCollection(skus, Sku.class);
        skuList.forEach(sku -> {
            sku.setSpuId(spu.getId());
        });
        int i = this.skuMapper.insertList(skuList);
        if (i!=skuList.size()){
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }

    }

    @Override
    public SpuDetailDTO queryGoodsById(Long id) {

       SpuDetail spuDetail = this.spuDetailMapper.queryGoodsBySpuId(id);
        SpuDetailDTO spuDetailDTO = BeanHelper.copyProperties(spuDetail, SpuDetailDTO.class);

        return spuDetailDTO;

    }

    @Override
    public List<SkuDTO> querySkuById(Long id) {
        List<Sku> skuList = this.skuMapper.querySkuById(id);
        List<SkuDTO> skuDTOS = BeanHelper.copyWithCollection(skuList, SkuDTO.class);

        return skuDTOS;
    }

    @Override
    public void updateSaleableById(Long id, Boolean sale) {
        this.spuMapper.updateSaleableById(id,sale);
        Sku sku = new Sku();
        sku.setSpuId(id);
        sku.setEnable(sale);
        this.skuMapper.updateByPrimaryKeySelective(sku);
    }

    @Override
    @Transactional
    public void updateGoods(SpuDTO spuDTO) {
        Long spuId = spuDTO.getId();
        if (spuId==null){
            throw new LyException(ExceptionEnum.INVALID_PARAM_ERROR);
        }
        Sku sku = new Sku();
        sku.setSpuId(spuId);
        int size = skuMapper.selectCount(sku);
        if (size>0){
            int count = skuMapper.delete(sku);
            if (count!=size){
                throw new LyException(ExceptionEnum.DELETE_DATA_ERROR);
            }
        }
        /**
         * 更新spu
         */
        Spu spu = BeanHelper.copyProperties(spuDTO, Spu.class);
        spu.setSaleable(null);
        spu.setCreateTime(null);
        spu.setUpdateTime(null);
        this.spuMapper.updateByPrimaryKeySelective(spu);
        /**
         * 更新spuDetail
         */

        SpuDetail spuDetail1 = BeanHelper.copyProperties(spuDTO.getSpuDetail(), SpuDetail.class);
        spuDetail1.setSpuId(spuId);
        spuDetail1.setCreateTime(null);
        spuDetail1.setUpdateTime(null);
        this.spuDetailMapper.updateByPrimaryKeySelective(spuDetail1);
        /**
         * 更新sku
         */
        List<SkuDTO> skus = spuDTO.getSkus();
        List<Sku> skuList = BeanHelper.copyWithCollection(skus, Sku.class);
        List<Sku> list = skuList.stream().map(sku1 -> {
            sku1.setEnable(false);
            sku1.setSpuId(spuId);
            return sku1;
        }).collect(Collectors.toList());
        int i = this.skuMapper.insertList(list);
        if (i!=list.size()){
         throw new LyException(ExceptionEnum.DATA_UPDATE_ERROR);
        }
    }

    @Override
    @Transactional
    public void deleteGoodsById(Long id) {
        this.spuMapper.deleteByPrimaryKey(id);
        this.spuDetailMapper.deleteSpuDetailBySpuId(id);
        this.skuMapper.deleteSkuBySpuId(id);
    }
}
